<%--
Copyright 2011 Michele Mancioppi [michele.mancioppi@gmail.com]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="com.google.appengine.api.utils.SystemProperty,java.util.*, javax.servlet.jsp.JspException,cave.nice.testMessage.data.*,com.google.appengine.api.users.*" %>
<%
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
if(user == null) {
	throw new JspException("The user must be logged in to access this page");
}
String emailAddress = user.getEmail(), nickname = user.getNickname(), deploymentId = SystemProperty.applicationId.get();
%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link type="text/css" href="/css/test-message.css" rel="stylesheet" />
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="/js/jquery.form.js"></script>
<script type="text/javascript" src="/js/jquery.editable.min.js"></script>
<script type="text/javascript" src="/js/jquery-ui.js"></script>
<script type="text/javascript" src="/js/jquery.dataTables.js"></script>
<script type="text/javascript" src="/js/jquery.dataTables.editable.js"></script>
<script type="text/javascript" src="/js/jquery.jeditable.js"></script>
<script type="text/javascript" src="/js/jquery.validate.js"></script>
<script type="text/javascript">
//<![CDATA[
var emailAddressesToTabs = new Object();
var emailAddressesToReportingPoliciesTables = new Object();

var verifiedAccountsTable = null;
var unverifiedAccountsTable = null;

var $verifiedAccountsTab = null;
var $unverifiedAccountsTab = null;

var selectedRowClass = 'row_selected';

$.validator.addMethod('positiveNumber',
    function (value) { 
        return Number(value) > 0;
    }, 'Please enter a positive number.');

$(document).ready(function() {
	loadTabs();
});

function loadTabs() {
	// Show loading screen
	var $loadingDialogMessage = $("<p>Loading the accounts</p>");
	var $loadingDialogProgressBar = $("<div id='progressbar'></div>");
	$loadingDialogProgressBar.progressbar();

	var $loadingDialog = $("<div></div>");
	$loadingDialog.append($loadingDialogMessage);
	$loadingDialog.append($loadingDialogProgressBar);
	$loadingDialog.dialog({
		title: "Loading...",
		modal: true
	});
	$loadingDialog.dialog("open");

	var $tabsContainer = $("div#tabsContainer");
	$tabsContainer.empty();

	var $tabsListDiv = $(document.createElement("div"));
	$tabsListDiv.attr("id", "tabs");
	$tabsListDiv.appendTo($tabsContainer);

	var $tabsList = $(document.createElement("ul"));
	$tabsList.appendTo($tabsListDiv);

	$loadingDialogMessage.text("Loading verified accounts");
	$loadingDialogProgressBar.progressbar( "option", "value", 50);

	$verifiedAccountsTab = $("<div id='verifiedAccountsTab' />");
	$tabsListDiv.append($verifiedAccountsTab);
	$tabsList.append($("<li><a href='#verifiedAccountsTab'>Verified email addresses</a></li>"));
	populateVerifiedAccountsTab();

	$loadingDialogMessage.text("Loading unverified accounts");
	$loadingDialogProgressBar.progressbar( "option", "value", 90);

	$unverifiedAccountsTab = $("<div id='unverifiedAccountsTab' />");
	$tabsListDiv.append($unverifiedAccountsTab);
	$tabsList.append($("<li><a href='#unverifiedAccountsTab'>Unverified email addresses</a></li>"));
	populateUnverifiedAccountsTab();

	$tabsListDiv.tabs();

	$("form#formAddNewRow").validate({
		rules: {
			notifyAfterMins: {
				required: true,
				positiveNumber: true
			}
		}
	});
	$("form#addUnverifiedAccountForm").validate({
		rules: {
			emailAddress: {
				required: true,
				email: true
			}
		}
	});
	$("form#formConfirmUnverifiedAccount").validate({
		rules: {
			challenge: {
				required: true
			}
		}
	});

	$loadingDialogMessage.text("Done!");
	$loadingDialogProgressBar.progressbar("option", "value", 100);

	$loadingDialog.dialog("close");
};

function populateVerifiedAccountsTab () {
	$verifiedAccountsTab.empty();

	var $accountsList = $("<ul id='verifiedAccountsList'></ul>");
	$accountsList.appendTo($verifiedAccountsTab);

	$.ajax({
		asynch: false,
		url: "/resources/accounts",
		type: "get",
		dataType: "json",
		success: function (data, textStatus, jqXHR) {
			// TODO Implement case for empty $data (i.e. no account registered)

			$(data).each(function(index) {
				var i = index + 1;
				var emailAddress = this.emailAddress;
				var registrationDate = new Date(this.registrationDate);
				//var reportingPolicies = this.reportingPolicies;

				var $accountLi = $("<li id='" + emailAddress + "'</li>");
				$accountLi.appendTo($accountsList);

				var $liTitle = $("<h3>" + emailAddress + "</h3>");
				$liTitle.appendTo($accountLi);
				
				var $accountDataDiv = $("<div class='accountData'></div>");
				$accountDataDiv.appendTo($accountLi);
				$accountDataDiv.append($("<p>Registered since: " + registrationDate + "</p>"));

				$liTitle.click(function(event) {
					$accountDataDiv.toggle();
				});

				var $deleteButton = $(document.createElement("button"));
				$deleteButton.appendTo($accountDataDiv);
				$deleteButton.button({
					label: "Delete email account",
					icons: { primary:'ui-icon-closethick' } 
				});
				$deleteButton.click(function() {
					// TODO Ask confirmation
					$.ajax({
						url: "/resources/accounts/" + emailAddress,
						type: "delete",
						success: function(data, textStatus, jqXHR) {
							loadTabs();
						},
						error: showAjaxError
					});
				});

				var $reportButton = $(document.createElement("button"));
				$reportButton.appendTo($accountDataDiv);
				$reportButton.button({
					label: "Show report",
					icons: { primary:'ui-icon-note' } 
				});
				$reportButton.click(function() {
					// TODO Ask confirmation
					var $reportContentDiv = $("div#reportContentDiv");
					var $reportDiv = $("div#reportFormDiv");
					var $reportForm = $reportDiv.find("form#reportForm");
					var $reportDialog = $reportDiv.dialog({
						autoOpen: false,
						draggable: true,
						resizable: true,
						modal: true,
						title: "Show report for the account " + emailAddress,
						buttons: {
							"Show": function () {
								$reportContentDiv.empty();
								var $selectedOption = $reportForm.find("option :selected");
								var value = $selectedOption.attr("value");
								/* value is one of: text, html, json */
								// TODO Implement "since"
								if (value != "json") {
									$iFrame = $(document.createElement("iframe"));
									$iFrame.appendTo($reportContentDiv);
									$iFrame.attr("src", "/resources/accounts/" + emailAddress +"/report?type=" + value);
								} else {
									// TODO Implement JSON case
								}
							}
						}
					});
					$reportDialog.dialog("open");
				});

				var $reportingPoliciesDiv = $(document.createElement("div"));
				$reportingPoliciesDiv.attr("id", "reportingPoliciesContainer");

				var $reportingPoliciesTitle = $("<h4>Reporting Policies</h4>");
				$reportingPoliciesTitle.appendTo($accountDataDiv);
				$reportingPoliciesTitle.click(function(event) {
					$reportingPoliciesDiv.toggle();
				});

				$reportingPoliciesDiv.appendTo($accountDataDiv);

				var $reportingPoliciesTable = $("<table id='reportingPolicies_" + emailAddress + "' class='datatable reportingPoliciesTable' />");
				$reportingPoliciesTable.appendTo($reportingPoliciesDiv);

				$("<thead><tr><th>Type</th><th>Notify after (mins)</th><th>Notify if no open tests</th></tr></thead>").appendTo($reportingPoliciesTable);

				var addNewReportingPolicyButtonId = "AddReportingPolicyButton" + i;
				var deleteReportingPolicyButtonId = "DeleteReportingPolicyButton" + i;
				var $divToolbar = $("<div class='toolbar'></div>");
				$divToolbar.appendTo($reportingPoliciesDiv);
				$("<button id='" + addNewReportingPolicyButtonId + "' />").appendTo($divToolbar);
				$("<button id='" + deleteReportingPolicyButtonId + "' />").appendTo($divToolbar);

				verifiedAccountsTable = $reportingPoliciesTable.dataTable({
					bProcessing: true,
					bJQueryUI: true,
					bAutoWidth: false,
					aoColumns: [{
							sTitle: "Type",
							sType: "string"
						},
						{
							sTitle: "Notify after (mins)",
							sType: "numeric"
						},
						{
							sTitle: "Notify if no open tests",
							bSearchable: false
						}],
					sAjaxSource: "/resources/accounts/" + emailAddress + "/reportingPolicies",
					fnServerData: function (sSource, aoData, fnCallback) {
						$.ajax({
							dataType: "json",
							type: "get",
							url: sSource,
							data: aoData,
							success: function (json) {
								var reportingPolicies = [], res = new Object();
								for(var i = 0, iLen = json.length; i < iLen; ++i) {
									var datum = json[i];
									var reportingPolicy = [datum["type"], datum["notifyAfterMinutes"], datum["notifyIfNoOpenTests"]];
									reportingPolicies.push(reportingPolicy);
								}

								res.aaData = reportingPolicies;
								fnCallback(res);
							}
						});
					}
				}).makeEditable({
					sSelectedRowClass: selectedRowClass,
					sAddHttpMethod: "post",
					sAddURL: "/resources/accounts/" + emailAddress + "/reportingPolicies",
					//sUpdateHttpMethod: "put",
					//sUpdateURL: "/resources/accounts/" + emailAddress + "/reportingPolicies",
					sDeleteHttpMethod: "delete",
					sDeleteURL: "/resources/accounts/" + emailAddress + "/reportingPolicies",
					oDeleteParameters: {
						type: function() {
							var type = $reportingPoliciesTable.find("tr." + selectedRowClass).find("td").first().text();
							return type;
						}
					},
					aoColumns: [
						null, // Not editable
						{
							sUpdateURL: "/resources/accounts/" + emailAddress + "/reportingPolicies/withMethodOverride",
							method: "PUT",
							indicator: 'Saving reporting after mins...',
							tooltip: 'Click to edit the time in minutes after which the notifications are sent',
							submit: 'Save changes',
							onblur: 'submit',
							name: "notifyAfterMinutes",
							submitdata: function () {
								var policyType = $(this).parents("tr").find("td").first().text();
								return { type: policyType };
							}
						},
						{
							sUpdateURL: "/resources/accounts/" + emailAddress + "/reportingPolicies/withMethodOverride",
							method: "PUT",
							indicator: 'Saving notify if no open tests...',
							tooltip: 'Click to change whether notifications are sent if no tests are open',
							submit: 'Save changes',
							onblur: 'submit',
							type: 'select',
							data: "{ 'true': 'true', 'false': 'false' }",
							name: "notifyIfNoOpenTests",
							submitdata: function () {
								var policyType = $(this).parents("tr").find("td").first().text();
								return { type: policyType };
							}
						}
					],
					sAddNewRowButtonId: addNewReportingPolicyButtonId,
					oAddNewRowButtonOptions: {
						label: "Add reporting policy",
						icons: { primary:'ui-icon-plus' } 
					},
					sAddNewRowFormId: "addNewRowForm",
					oAddNewRowFormOptions: {
						title: "Add a new reporting policy",
						show: "blind",
						hide: "explode",
						modal: true
					},
					sDeleteRowButtonId: deleteReportingPolicyButtonId,
					oDeleteRowButtonOptions: {
						label: "Remove reporting policy", 
						icons: { primary:'ui-icon-closethick' }
					},
					fnShowError: showError
				});
			});
		},
		error: showAjaxError
	});
};

function populateUnverifiedAccountsTab () {
	$unverifiedAccountsTab.empty();

	var $unverifiedAccountsTable = $("<table id='unverifiedAccountsTable' class='datatable' />");
	$unverifiedAccountsTab.append($unverifiedAccountsTable);

	var addUnverifiedAccountButtonId = "AddUnverifiedAccountButton";
	var deleteUnverifiedAccountButtonId = "DeleteUnverifiedAccountButton";
	var $toolbar = $("<div class='toolbar'></div>");
	$toolbar.append("<button id='" + addUnverifiedAccountButtonId + "' />")

	$toolbar.append("<button id='" + deleteUnverifiedAccountButtonId + "' />")
	$toolbar.appendTo($unverifiedAccountsTab);

	unverifiedAccountsTable = $unverifiedAccountsTable.dataTable({
		bProcessing: true,
		bJQueryUI: true,
        sAjaxSource: "/resources/unverifiedAccounts",
        aoColumns:
			[{
				sTitle: "Email address",
				sType: "string"
			},
			{
				sTitle: "Registration date",
				sType: "date"
			}],
		fnServerData: function (sSource, aoData, fnCallback) {
			$.ajax({
				dataType: "json",
				type: "get",
				url: sSource,
				data: aoData,
				success: function (json) {
					var unverifiedAccounts = [], res = new Object();
					for(var i = 0, iLen = json.length; i < iLen; ++i) {
						var datum = json[i];
						var unverifiedAccount = [datum["emailAddress"], new Date(datum["registrationDate"])];
						unverifiedAccounts.push(unverifiedAccount);
					}

					res.aaData = unverifiedAccounts;
					fnCallback(res);
				}
			});
		},
		fnRowCallback: function(nRow, aData, iDisplayIndex) {
			return nRow;
		}
	}).makeEditable({
		aoColumns: [ null, null ],
		sSelectedRowClass: selectedRowClass,
		sAddURL: "/resources/unverifiedAccounts",
		sAddHttpMethod: "post",
		sUpdateURL: "/resources/unverifiedAccounts",
		sUpdateHttpMethod: "put",
		sDeleteURL: "/resources/unverifiedAccounts",
		sDeleteHttpMethod: "delete",
		oDeleteParameters: {
			emailAddress: function() {
				var selectedRow = $unverifiedAccountsTable.find("tr." + selectedRowClass);
				return $(selectedRow).attr("id");
			}
		},
		sAddNewRowButtonId: addUnverifiedAccountButtonId,
		oAddNewRowButtonOptions: {
			label: "Add email account",
			icons: { primary:'ui-icon-plus' } 
		},
		sAddNewRowFormId: "addUnverifiedAccountForm",
		oAddNewRowFormOptions: {
			title: "Add a new email account",
			show: "blind",
			hide: "explode",
			modal: true
		},
		sDeleteRowButtonId: deleteUnverifiedAccountButtonId,
		oDeleteRowButtonOptions: {
			label: "Remove email account", 
			icons: { primary:'ui-icon-closethick' }
		},
		fnShowError: showError
	});

	var $confirmButton = $(document.createElement("button"));
	$confirmButton.attr("id", "confirmButton");
	$confirmButton.button({
		disabled: true,
		label: "Confirm email account",
		icons: {
			primary: "ui-icon-wrench"
		}
	});
	$confirmButton.click(function (event) {
		var $selectedRow = unverifiedAccountsTable.find("tr." + selectedRowClass).first();
		var emailAddress = $selectedRow.find("td").first().text();

		var $form = $("form#confirmUnverifiedAccountForm");
		var $dialog = $form.dialog({
			autoOpen: false,
			buttons: [
				{
					text: "Confirm",
					click: function() {
						$form.ajaxSubmit({
							url: "/resources/unverifiedAccounts/" + emailAddress + "/confirmation",
							type: "put",
							success: function (data, textStatus, jqXHR) {
								populateVerifiedAccountsTab();
								populateUnverifiedAccountsTab();
								$dialog.dialog("close");
							},
							error: showAjaxError
						});
					}
				}
			],
			draggable: false,
			modal: true,
			resizable: false,
			title: "Confirm email account '" + emailAddress + "'"
		});
		$dialog.dialog("open");
	});
	$confirmButton.appendTo($toolbar);

	var $resendConfirmationButton = $(document.createElement("button"));
	$resendConfirmationButton.attr("id", "resendConfirmationButton");
	$resendConfirmationButton.button({
		disabled: true,
		label: "Resend confirmation email",
		icons: {
			primary: "ui-icon-mail-closed"
		}
	});
	$resendConfirmationButton.click(function (event) {
		var $selectedRow = unverifiedAccountsTable.find("tr." + selectedRowClass).first();
		var emailAddress = $selectedRow.find("td").first().text();

		var $dialog = $(document.createElement("div"));
		$dialog.text("Re-sending the verification email to the account " + emailAddress +". This dialog will close when the dispatching is completed.");
		// TODO Remove default closing button
		$dialog.dialog({
			title: "Re-sending the verification email",
			modal: true,
			resizable: false,
			draggable: false,
			closeOnEscape: false
		});
		$dialog.dialog("open");

		$.ajax({
			url: "/resources/unverifiedAccounts/" + emailAddress + "/verificationMessageRequest",
			type: "post",
			success: function (data, textStatus, jqXHR) {
				// Show a dialog?
			},
			error: function (jqXHR, textStatus, errorThrown) {
				showAjaxError (jqXHR, textStatus, errorThrown);
			},
			complete: function (jqXHR, textStatus) {
				$dialog.dialog("close");
			}
		});
	});
	$resendConfirmationButton.appendTo($toolbar);

	$("tbody", unverifiedAccountsTable).click(function (event) {
		if ($(event.target.parentNode).hasClass(selectedRowClass)) {
        	$confirmButton.button("enable");
        	$resendConfirmationButton.button("enable");
        } else {
        	$confirmButton.button("disable");
        	$resendConfirmationButton.button("disable");
        }
    });
};

function showAjaxError (jqXHR, textStatus, errorThrown) {
	alert ("ERROR: " + errorThrown);
};

function showError(message, action) {
	alert ("ERROR (Action: " + action +"; message: " + message + ")");
}
//]]>
</script>
<title>Accounts of <%= nickname %> on <%= deploymentId %></title>
</head>
<body>
<h1>Accounts of <%= nickname %> on <%= deploymentId %></h1>
<div id="tabsContainer"></div>
<div style="display: none">
<form id="addNewRowForm" action="#">
<label for="type">Reporting policy type:</label>
<select name="type" rel="0">
<option value="GMail">GMail</option>
<option value="GTalk">GTalk</option>
</select>
<br />
<label for="notifyAfterMinutes">Notify after (mins):</label>
<input type="text" name="notifyAfterMinutes" rel="1" />
<br />
<label for="notifyIfNoOpenTests">Notify if no open tests:</label>
<select name="notifyIfNoOpenTests" rel="2">
<option selected="selected" value="false">false</option>
<option value="true">true</option>
</select>
</form>
</div>
<form id="addUnverifiedAccountForm" style="display: none" action="#">
<label for="emailAddress">Email Address:</label>
<input type="text" name="emailAddress" rel="0" />
<input type="hidden" name="registrationDate" rel="1" value="---" />
</form>
<form id="confirmUnverifiedAccountForm" style="display: none" action="#">
<label for="challenge">Challenge:</label>
<input type="text" name="challenge" />
</form>
<div id="reportFormDiv" style="display: none">
<form id="reportForm" action="#">
<label for="type">Report type:</label>
<select id="reportTypeSelect" name="type">
<option id="reportSelectPlainOption" selected="selected" value="text">Plain text</option>
<!-- <option id="reportSelectHTMLOption" value="html">HTML</option> -->
<option id="reportSelectJSONOption" value="json">Dynamic</option>
</select>
</form>
<div id="reportContentDiv"></div>
</div>
</body>
</html>